package cn.lg.soar.core.excel.strategy;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 行合并策略（向下合并）
 * @author luguoxiang 469599794@qq.com
 * @Date: 2024/3/7 16:06
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class RowMergeStrategy extends AbstractMergeStrategy {

	private final Map<Integer, Info> map;
	private final int dataSize;

	public RowMergeStrategy(int dataSize, int... mergeCellIndexes) {
		this.dataSize = dataSize - 1;
		this.map = new HashMap<>();
		for (int cellIndex : mergeCellIndexes) {
			this.map.put(cellIndex, null);
		}
	}

	public RowMergeStrategy(int dataSize, Collection<Integer> mergeCellIndexes) {
		this.dataSize = dataSize - 1;
		this.map = new HashMap<>();
		for (int cellIndex : mergeCellIndexes) {
			this.map.put(cellIndex, new Info());
		}
	}

	@Override
	protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
		if (relativeRowIndex == null) {
			return;
		}
		int columnIndex = cell.getColumnIndex();
		Info info = map.get(columnIndex);
		if (info == null) {
			return;
		}
		int rowIndex = cell.getRowIndex();
		String value = CellType.NUMERIC.equals(cell.getCellType()) ? String.valueOf(cell.getNumericCellValue()) : cell.getStringCellValue();
		if (Objects.equals(info.value, value)) {
			if (!Objects.equals(this.dataSize, relativeRowIndex)) {
				info.endRowIndex = rowIndex;
				return;
			}
			info.endRowIndex = rowIndex;
			rowIndex += 1;
		}
		if (info.endRowIndex != info.startRowIndex && info.endRowIndex == rowIndex - 1) {
			sheet.addMergedRegionUnsafe(
					new CellRangeAddress(info.startRowIndex, info.endRowIndex, columnIndex, columnIndex)
			);
		}
		info.value = value;
		info.startRowIndex = rowIndex;
		info.endRowIndex = rowIndex;
	}

	private static class Info {
		private int startRowIndex;
		private int endRowIndex;
		private String value;
	}
}


